package com.zhiche.lisa.bms.service.arfund.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zhiche.lisa.bms.dao.mapper.arfund.ArFundMapper;
import com.zhiche.lisa.bms.dao.model.arfund.ArFund;
import com.zhiche.lisa.bms.dao.model.pay.PayApplyDtlFund;
import com.zhiche.lisa.bms.pojo.dto.driver.DriverDTO;
import com.zhiche.lisa.bms.pojo.dto.fleet.FleetDTO;
import com.zhiche.lisa.bms.pojo.vo.arFund.ArFundVO;
import com.zhiche.lisa.bms.service.arfund.ArFundService;
import com.zhiche.lisa.bms.service.fee.FeeReceivableService;
import com.zhiche.lisa.bms.service.pay.PayApplyDtlFundService;
import com.zhiche.lisa.bms.service.utils.LspUtil;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.utils.Account.AccountUtil;
import com.zhiche.lisa.core.utils.Account.JwtAccountVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 * 应收款项 服务实现类
 * </p>
 *
 * @author hongbo
 * @since 2018-09-20
 */
@Service
public class ArFundServiceImpl extends ServiceImpl<ArFundMapper, ArFund> implements ArFundService {
    private static final Logger LOGGER = LoggerFactory.getLogger(FeeReceivableService.class);
    @Autowired
    private LspUtil lspUtil;

    @Autowired
    private PayApplyDtlFundService payApplyDtlFundService;

    /**
     * 应收款项分页查询
     *
     * @param pageVo
     * @return
     */
    @Override
    public Page<ArFund> queryArFundLinePage(Page<ArFundVO> pageVo) {
        try {
            EntityWrapper<ArFund> ew = this.buildCondition(pageVo.getCondition());
            pageVo.setCondition(Maps.newHashMap());
            List<ArFund> list = baseMapper.selectPage(pageVo, ew);
            Page<ArFund> page = new Page<>();
            BeanUtils.copyProperties(pageVo, page);
            page.setRecords(list);
            return page;
        } catch (BaseException e) {
            LOGGER.error("ArFundServiceImpl.lisaFeeReceivableLinePage:" + e.getMessage());
            throw new BaseException("获取应收款项失败");
        } catch (Exception e) {
            LOGGER.error("ArFundServiceImpl.lisaFeeReceivableLinePage:" + e.getMessage());
            throw e;
        }
    }

    private EntityWrapper<ArFund> buildCondition(Map<String, Object> condition) {
        EntityWrapper<ArFund> ew = new EntityWrapper<>();
        ew.orderBy("gmt_create desc, id desc");
        if (!Objects.equals(condition, null)) {
            for (Map.Entry<String, Object> entry : condition.entrySet()) {
                if (Objects.nonNull(entry.getValue())) {
                    if (!StringUtils.isEmpty(String.valueOf(entry.getValue()))) {
                        if ("lspName".equals(entry.getKey()) && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.like("lsp_name", String.valueOf(entry.getValue()));
                        }
                        if ("lspId".equals(entry.getKey()) && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.like("lsp_id", String.valueOf(entry.getValue()));
                        }
                        if ("fleetName".equals(entry.getKey()) && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.eq("fleet_name", String.valueOf(entry.getValue()));
                        }
                        if ("fleetId".equals(entry.getKey()) && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.eq("fleet_id", String.valueOf(entry.getValue()));
                        }
                        if ("driverName".equals(entry.getKey()) && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.eq("driver_name", String.valueOf(entry.getValue()));
                        }
                        if ("driverId".equals(entry.getKey()) && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.eq("driver_id", String.valueOf(entry.getValue()));
                        }
                        if ("withholdWay".equals(entry.getKey()) && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.eq("withhold_way", String.valueOf(entry.getValue()));
                        }
                        if ("status".equals(entry.getKey()) && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.eq("status", String.valueOf(entry.getValue()));
                        }
                        if ("gtBalance".equals(entry.getKey()) && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.gt("balance", String.valueOf(entry.getValue()));
                        }
                        if ("gmtCreate".equals(entry.getKey()) && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.ge("gmt_create", String.valueOf(entry.getValue()));
                        }
                        if ("gmtCreateVo".equals(entry.getKey()) && StringUtils.isNoneBlank(entry.getValue().toString())) {
                            ew.le("gmt_create", String.valueOf(entry.getValue()));
                        }
                    }
                }
            }
        }
        ew.orderBy("gmt_create desc, id desc");
        return ew;
    }

    /**
     * 新增应收款项
     *
     * @param list
     */
    @Override
    public List<String> insertArFund(List<ArFund> list) {
        try {
            if (CollectionUtils.isEmpty(list)) {
                throw new BaseException("未获取导入数据");
            }
            List<String> msg = new ArrayList<>();
            List<ArFund> arFunds = new ArrayList<>();
            int i = 0;
            JwtAccountVO jwtAccountVO = AccountUtil.getAccountInfoFromSecurityContext();
            Long tentId = null;
            if (Objects.nonNull(jwtAccountVO)) {
                tentId = Long.valueOf(jwtAccountVO.getTenantId());
            }
            for (ArFund arFund : list) {
                if (Objects.nonNull(arFund)) {
                    i++;
                    if (StringUtils.isNotEmpty(arFund.getWithhold()) && StringUtils.isNotEmpty(arFund.getFleetName()) && StringUtils.isNotEmpty(arFund.getLspName()) && !(arFund.getSum() == null)) {
                        if ("油卡".equals(arFund.getWithholdWay())) {
                            arFund.setWithholdWay("0");
                        } else if ("现金".equals(arFund.getWithholdWay())) {
                            arFund.setWithholdWay("1");
                        }
                        if(arFund.getSum()==null){
                            arFund.setSum(BigDecimal.ZERO);
                        }
                        if(arFund.getBalance()==null){
                            arFund.setBalance(arFund.getSum());
                        }
                        if(arFund.getExecuteSum()==null){
                            arFund.setExecuteSum(arFund.getSum().subtract(arFund.getBalance()));
                        }
                        arFund.setStatus(0);
                        arFund.setGmtCreate(new Date());
                        arFund.setTenantId(tentId);
                        arFunds.add(arFund);
                    } else {
                        //主要信息遗漏反馈
                        lostMessageBackForInsert(arFund, msg, i);
                    }
                }
            }
            if (CollectionUtils.isNotEmpty(arFunds)) {
                this.insertBatch(arFunds);
            }
            return msg;
        } catch (BaseException e) {
            LOGGER.error("ArFundServiceImpl.insertArFund: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            LOGGER.error("ArFundServiceImpl.insertArFund: {}", e.getMessage());
            throw new BaseException("新增应收款项失败!");
        }
    }

    /**
     * 信息反馈
     *
     * @param arFund
     * @param msg
     * @param i
     */
    private void lostMessageBackForInsert(ArFund arFund, List<String> msg, int i) {
        String msr = "导入失败:" + "第" + String.valueOf(i) + "条数据:";
        if (StringUtils.isEmpty(arFund.getWithhold())) {
            msr = msr + "扣款项为空,";
        }
        if (StringUtils.isEmpty(arFund.getLspName())) {
            msr = msr + "承运商为空,";
        }
        if (StringUtils.isEmpty(arFund.getFleetName())) {
            msr = msr + "车队信息为空,";
        }
        if (arFund.getSum() == null) {
            msr = msr + "金额信息为空,";
        }
        msg.add(msr);
    }

    /**
     * 应收款项批量删除
     *
     * @param ids
     */
    @Override
    public void deleteArFund(List<Long> ids) {
        try {
            if (CollectionUtils.isEmpty(ids)) {
                throw new BaseException("未选中应收款项");
            }
            EntityWrapper<ArFund> ew = new EntityWrapper<>();
            ew.in("id", ids);
            ew.eq("status", 0);
            int count = this.selectCount(ew);
            if (count != ids.size()) {
                throw new BaseException("存在非新增状态的数据，不可删除");
            }
            this.deleteBatchIds(ids);
        } catch (BaseException e) {
            LOGGER.error("ArFundServiceImpl.deleteArFund:" + e.getMessage());
            throw e;
        } catch (Exception e) {
            LOGGER.error("ArFundServiceImpl.deleteArFund:" + e.getMessage());
            throw new BaseException("删除应收款项失败!");
        }
    }

    /**
     * 应收款项审核
     *
     * @param ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<String> examineArFund(List<Long> ids, String token) {
        try {
            if (CollectionUtils.isEmpty(ids)) {
                throw new BaseException("未选中应收款项");
            }
            List<ArFund> arFunds = this.selectBatchIds(ids);
            //获取承运商信息
            Map<Long, Long> lspMap = lspUtil.queryLspByName(arFunds, token);
            //获取车队信息
            Map<Long, FleetDTO> fleetMap = lspUtil.queryFleetByName(arFunds, token);
            //获取司机信息
            Map<Long, DriverDTO> driverMap = lspUtil.queryDriverByName(arFunds, token);
            List<ArFund> arFundss = new ArrayList<>();
            List<String> msg = new ArrayList<>();
            //审核
            for (ArFund arFund : arFunds) {
                if (arFund.getStatus() == 0) {
                    //判断是否有司机名称
                    if (StringUtils.isNotEmpty(arFund.getDriverName())) {
                        Long id = arFund.getId();
                        if (Objects.nonNull(lspMap.get(id)) && Objects.nonNull(fleetMap.get(id)) && Objects.nonNull(driverMap.get(id))) {
                            if (lspMap.get(id).equals(fleetMap.get(id).getLspId()) && lspMap.get(id).equals(driverMap.get(id).getLspId())) {
                                arFund.setLspId(lspMap.get(id));
                                arFund.setFleetId(fleetMap.get(id).getId());
                                arFund.setDriverId(driverMap.get(id).getId());
                                arFund.setDriverMobile(driverMap.get(id).getMobile());
                                arFund.setStatus(1);
                                arFundss.add(arFund);
                            } else {
                                //反馈遗失信息
                                lostMessageBackForExamine(msg, arFund, lspMap, fleetMap, driverMap);
                            }
                        } else {
                            //反馈遗失信息
                            lostMessageBackForExamine(msg, arFund, lspMap, fleetMap, driverMap);
                        }
                    } else if (StringUtils.isEmpty(arFund.getDriverName())) {
                        Long id = arFund.getId();
                        if (Objects.nonNull(lspMap.get(id)) && Objects.nonNull(fleetMap.get(id)) && lspMap.get(id).equals(fleetMap.get(id).getLspId())) {
                            arFund.setLspId(lspMap.get(id));
                            arFund.setFleetId(fleetMap.get(id).getId());
                            arFund.setStatus(1);
                            arFundss.add(arFund);
                        } else {
                            //反馈遗失信息
                            lostMessageBackForExamine(msg, arFund, lspMap, fleetMap, driverMap);
                        }
                    }
                }
            }
            if (CollectionUtils.isNotEmpty(arFundss)) {
                this.updateBatchById(arFundss);
            }
            return msg;
        } catch (BaseException e) {
            LOGGER.error("ArFundServiceImpl.examineArFund:" + e.getMessage());
            throw e;
        } catch (Exception e) {
            LOGGER.error("ArFundServiceImpl.examineArFund:" + e.getMessage());
            throw new BaseException("应收款项审核失败!");
        }
    }

    /**
     * 遗失信息反馈
     *
     * @param msg
     * @param arFund
     * @param lspMap
     * @param fleetMap
     * @param driverMap
     */
    private void lostMessageBackForExamine(List<String> msg, ArFund arFund, Map<Long, Long> lspMap, Map<Long, FleetDTO> fleetMap, Map<Long, DriverDTO> driverMap) {
        String msr = "扣款项:" + arFund.getWithhold() + ":" + arFund.getLspName();
        if (StringUtils.isNotEmpty(arFund.getDriverName())) {
            if (Objects.nonNull(lspMap.get(arFund.getId()))) {
                if (Objects.nonNull(fleetMap.get(arFund.getId()))) {
                    if (!lspMap.get(arFund.getId()).equals(fleetMap.get(arFund.getId()).getLspId())) {
                        msr = msr + "车队中的承运商不匹配";
                        msg.add(msr);
                    } else if (Objects.nonNull(driverMap.get(arFund.getId()))) {
                        if (!lspMap.get(arFund.getId()).equals(driverMap.get(arFund.getId()).getLspId())) {
                            msr = msr + "司机中的承运商不匹配";
                            msg.add(msr);
                        }
                    } else {
                        msr = msr + "未获取司机信息";
                        msg.add(msr);
                    }
                } else {
                    msr = msr + "未获取车队信息";
                    msg.add(msr);
                }
            } else {
                msr = msr + "未获取承运商信息";
                msg.add(msr);
            }
        } else {
            if (Objects.nonNull(lspMap.get(arFund.getId()))) {
                if (Objects.nonNull(fleetMap.get(arFund.getId()))) {
                    if (!lspMap.get(arFund.getId()).equals(fleetMap.get(arFund.getId()).getLspId())) {
                        msr = msr + "车队中的承运商不匹配";
                        msg.add(msr);
                    }
                } else {
                    msr = msr + "未获取车队信息";
                    msg.add(msr);
                }
            } else {
                msr = msr + "未获取承运商信息";
                msg.add(msr);
            }
        }
    }

    /**
     * 根据支付申请Id，查询其他扣款列表
     * @param payId
     * @return
     */
    @Override
    public List<ArFund> getArFundLineByPayIdList(Long payId) {
        if (ObjectUtils.isEmpty(payId)) {
            return null;
        }
        List<PayApplyDtlFund> payApplyDtlFundsList = payApplyDtlFundService.queryPayApplyDtlFundList(payId);
        if (CollectionUtils.isEmpty(payApplyDtlFundsList)) {
            return null;
        }
        List<Long> billIds = Lists.newArrayList();
        payApplyDtlFundsList.forEach(payApplyDtlBill -> {
            if (!ObjectUtils.isEmpty(payApplyDtlBill.getBilId())) {
                billIds.add(payApplyDtlBill.getBilId());
            }
        });
        if (CollectionUtils.isEmpty(billIds)) {
            return null;
        }
        EntityWrapper ew = new EntityWrapper<>();
        ew.in("id", billIds);
        return this.selectList(ew);
    }

    @Override
    public List<ArFund> getArFundById(List<Long> ids) {
        EntityWrapper ew = new EntityWrapper<>();
        ew.in("id", ids);
        return this.selectList(ew);
    }

    @Override
    public List<Long> getFeePayableSumByFeepIdAndIds(Long feePayableId, List<Long> ids) {
        return baseMapper.getFeePayableSumByFeepIdAndIds(feePayableId, ids);
    }
}
